﻿// ****************************************************************************
// <copyright file="EventToCommand.WPF.cs" company="GalaSoft Laurent Bugnion">
// Copyright © GalaSoft Laurent Bugnion 2009-2012
// </copyright>
// ****************************************************************************
// <author>Laurent Bugnion</author>
// <email>laurent@galasoft.ch</email>
// <date>3.11.2009</date>
// <project>GalaSoft.MvvmLight.Extras</project>
// <web>http://www.galasoft.ch</web>
// <license>
// See license.txt in this solution or http://www.galasoft.ch/license_MIT.txt
// </license>
// ****************************************************************************
// This partial class contains the WPF-only implementation. See
// EventToCommand.cs for the shared implementation, and EventToCommand.SL.cs
// for the Silverlight-only implementation.
// ****************************************************************************
using System.Windows;
using System.Windows.Input;

namespace TimersXP.CommandBase
{
    /// <summary>
    /// This <see cref="System.Windows.Interactivity.TriggerAction"/> can be used to bind any event on any FrameworkElement to an <see cref="ICommand"/>.
    /// Typically, this element is used in XAML to connect the attached element to a command located in a ViewModel.
    /// This trigger can only be attached to a FrameworkElement or a class deriving from FrameworkElement.
    /// </summary>
    public partial class EventToCommand
    {
        /// <summary>Identifies the <see cref="CommandParameter"/> dependency property.</summary>
        public static readonly DependencyProperty CommandParameterProperty = DependencyProperty.Register(
            "CommandParameter",
            typeof(object),
            typeof(EventToCommand),
            new PropertyMetadata(
                null,
                (s, e) =>
                {
                    var sender = s as EventToCommand; ;
                    if (sender == null)
                        return;

                    if (sender.AssociatedObject == null)
                        return;

                    sender.EnableDisableElement();
                }));

        /// <summary>Identifies the <see cref="Command"/> dependency property.</summary>
        public static readonly DependencyProperty CommandProperty = DependencyProperty.Register(
            "Command", typeof(ICommand), typeof(EventToCommand), new PropertyMetadata( null, (s, e) => OnCommandChanged(s as EventToCommand, e)));

        /// <summary>Identifies the <see cref="MustToggleIsEnabled"/> dependency property.</summary>
        public static readonly DependencyProperty MustToggleIsEnabledProperty = DependencyProperty.Register(
            "MustToggleIsEnabled", typeof(bool), typeof(EventToCommand), new PropertyMetadata(false,  (s, e) =>
                {
                    var sender = s as EventToCommand;
                    if (sender == null)
                        return;

                    if (sender.AssociatedObject == null)
                        return;

                    sender.EnableDisableElement();
                }));

        /// <summary>The command parameter value</summary>
        private object commandParameterValue;

        /// <summary>The must toggle value.</summary>
        /// <NOTE>The "?" means it is a nullable variable.</NOTE>
        private bool? mustToggleValue;

        /// <summary>Gets or sets the ICommand that this trigger is bound to. This is a DependencyProperty.</summary>
        /// <value>The command.</value>
        public ICommand Command
        {
            get { return (ICommand)GetValue(CommandProperty); }
            set { SetValue(CommandProperty, value); }
        }

        /// <summary>Gets or sets an object that will be passed to the <see cref="Command"/> attached to this trigger. This is a DependencyProperty.</summary>
        /// <value>The command parameter.</value>
        public object CommandParameter
        {
            get { return this.GetValue(CommandParameterProperty); }
            set { SetValue(CommandParameterProperty, value); }
        }

        /// <summary>
        /// Gets or sets an object that will be passed to the <see cref="Command"/> attached to this trigger. This property is here for compatibility with the Silverlight version.
        /// This is NOT a DependencyProperty. For databinding, use the <see cref="CommandParameter"/> property.
        /// </summary>
        /// <value>The command parameter value.</value>
        public object CommandParameterValue
        {
            get { return this.commandParameterValue ?? this.CommandParameter; }
            set 
            {
                commandParameterValue = value;
                EnableDisableElement();
            }
        }

        /// <summary>
        /// Gets or sets a value indicating whether the attached element must be disabled when the <see cref="Command"/> property's CanExecuteChanged event fires.
        /// If this property is true, and the command's CanExecute method returns false, the element will be disabled.
        /// If this property is false, the element will not be disabled when the command's CanExecute method changes. This is a DependencyProperty.
        /// </summary>
        /// <value><c>true</c> if [must toggle is enabled]; otherwise, <c>false</c>.</value>
        public bool MustToggleIsEnabled
        {
            get { return (bool)this.GetValue(MustToggleIsEnabledProperty); }
            set { SetValue(MustToggleIsEnabledProperty, value); }
        }

        /// <summary>
        /// Gets or sets a value indicating whether the attached element must be disabled when the <see cref="Command"/> property's CanExecuteChanged element fires.
        /// If this property is true, and the command's CanExecute method returns false, the element will be disabled.
        /// This property is here for compatibility with the Silverlight version. This is NOT a DependencyProperty. For databinding, use the <see cref="MustToggleIsEnabled"/> property.
        /// </summary>
        /// <value><c>true</c> if [must toggle is enabled value]; otherwise, <c>false</c>.</value>
        public bool MustToggleIsEnabledValue
        {
            get { return this.mustToggleValue == null ? this.MustToggleIsEnabled : this.mustToggleValue.Value; }
            set
            {
                this.mustToggleValue = value;
                EnableDisableElement();
            }
        }

        /// <summary>Called after the action is attached to a DependencyObject.</summary>
        protected override void OnAttached()
        {
            base.OnAttached();
            EnableDisableElement();
        }

        /// <summary>This method is here for compatibility with the Silverlight version.</summary>
        /// <returns>The object to which this trigger is attached casted as a FrameworkElement</returns>
        private FrameworkElement GetAssociatedObject() { return AssociatedObject as FrameworkElement; }

        /// <summary>This method is here for compatibility with the Silverlight version.</summary>
        /// <returns>The command that must be executed when this trigger is invoked.</returns>
        private ICommand GetCommand() { return Command; }
    }
}
